package table;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;

import audit.AuditWriter;

import userInterface.GUIController;

import fileProcessing.ParsingException;
import fileProcessing.ProjectDirectories;


public class TableCollection {
	private static final TableCollection tableSingleton = new TableCollection();
	private HashMap<String, Table> tableCollection = new HashMap<String, Table>(
			100);
	public static AuditWriter audit;
	private TableCollection() {
		try {
			audit = AuditWriter.getAuditWriter();
		} catch (ParsingException e) {
		}
	}
	
	
	/**
	 * Provides one instance of TableCollection for use throughout the project
	 * @return Instance of TableCollection
	 */
	public static TableCollection getTableHashClass(){
		return tableSingleton;
	}
	
	/**
	 * Getter for the tableCollection hashmap
	 * @return TableCollection.tableCollection hashmap of all database tables
	 */
	public HashMap<String,Table> getTableCollection(){
		return tableCollection;
	}
	/**
	 * Getter for the number of tables in tableCollection
	 * @return Number of tables stored in database
	 */
	public int getSize() {
		return tableCollection.size();
	}

	/**
	 * Adds a new table to the database
	 * 
	 * @param table New table to be added
	 * @throws ParsingExceptions Fail if table already exists in database
	 */
	public void addTable(Table table) throws ParsingException {
		if(tableCollection.containsKey(table.getTableName()))
			throw new ParsingException("Table already exists in database, please redeclare with new name.");
		else
			tableCollection.put(table.getTableName(), table);
	}

	/**
	 * Supports the command "Drop", allowing a user to remove a table from the
	 * database.
	 * 
	 * @param tableName
	 * @throws IOException
	 */
	public void deleteTable(String tableName) {
		tableCollection.remove(tableName).delete();		
	}

	/**
	 * Prints a list of all tables' names along with their associated fields and
	 * field types.
	 * 
	 * @throws IOException
	 */
	public String printTable(String tableName) throws ParsingException {
		Table thisTable = tableCollection.get(tableName);
		String s = "";
		if (thisTable == null)
			throw new ParsingException("Table name not found");
		else {
			s += "This table is:\t" + tableName + "\n";
			s += thisTable.getTableInfo();
		}
		return s;
	}
	
	public void outputToCSV(String delimiter) throws ParsingException{
		try {
			for(String r : tableCollection.keySet()){
				audit.writeToAudit("Outputting " + r + ".csv");
				GUIController.getMainPage().setStatus("Outputting " + r + ".csv");
				BufferedWriter bw_CSV = new BufferedWriter(new FileWriter((ProjectDirectories.outputFileDir+"\\"+r+".csv")));
				tableCollection.get(r).toCSV(bw_CSV,delimiter);
				bw_CSV.close();
				GUIController.getMainPage().setStatus(" ...done\n");
			}
		} catch (IOException e) {
			throw new ParsingException("Error writing CSV file for record: "+ e.getMessage());
		}
	}
}
